﻿using System;
using System.Collections.Generic;
using System.Xml.Serialization;
using DC2010.Objects.Base;
using DC2010.Objects.Common;
using DC2010.Objects.Logic;

namespace DC2010.Objects
{
    [Serializable]
    public class CreatureData : BaseData
    {
        public CreatureData()
        {
            Inventory = new Inventory();
            Attributes = new Attributes();
            Resistances = new Resistances();
			Abilities = new CreatureAbilites();
			Flags = new CreatureFlags();
			AIFlags = new CreatureAIFlags();
			
			Skills = new SKILL[20];
            Location = new DungeonLoc();
        }

		#region Can be changed, but are initiated from Info
        public Attributes Attributes { get; set; }
		
        /// <summary>
        /// Items in inventory
        /// </summary>
        public Inventory Inventory { get; set; }	

		/// <summary>
		/// Mutace?
		/// <summary>
        [XmlAttribute]
        public CreatureType CreatureType { get; set; }
        public CreatureAbilites Abilities { get; set; }		
        public CreatureFlags Flags { get; set; }		
        public CreatureOuches Ouches { get; set; }	
		public CreatureAIFlags AIFlags { get; set; } 		

		public Resistances Resistances { get; set; }	
				
        /// <summary>
        /// Reaction range of monster in squares.
        /// </summary>
        public int SightRange { get; set; }
		
		
        public SKILL[] Skills { get; set; }		

		#endregion		

		#region Very dynamic properties
        /// <summary>
        /// In Dungeon Master and Chaos Strikes Back, the character sheet of a champion shows the load that the champion is currently carrying and the maximum load he is able to carry. We will call these values CurrentLoad and MaxLoad.
        /// The MaxLoad value depends on the current value of strength and the current and maximum values of stamina.
        /// The current strength value is used to determine a base maximum load value. We will call this value BaseMaxLoad.
        /// </summary>
        /// <remarks>
        /// The BaseMaxLoad value is then adjusted using the current and maximum stamina values to determine the MaxLoad value that is displayed in the character sheet:
        /// If Stamina vetsi nebo rovno MaxStamina/2 Then MaxLoad is equal to BaseMaxLoad
        /// If Stamina mensi MaxStamina/2 Then MaxLoad is equal to BaseMaxLoad / 2 + ((BaseMaxLoad * Stamina) / (MaxStamina / 2))
        /// If CurrentLoad is greater than 5/8th of MaxLoad, the current and maximum load values are displayed in yellow.
        /// If CurrentLoad is greater than MaxLoad, the current and maximum load values are displayed in red.
        /// The interesting thing to notice is that when the current stamina value is between a half and a quarter of the maximum stamina value, the maximum load value is greater than the base maximum load!
        /// For example, let's take a champion with
        /// CurrentStrength = 60
        /// MaxStamina = 160
        /// For this champion, BaseMaxLoad = (8 x 60 + 100) / 10 = 58 Kg
        /// If this champion has a current stamina level between 80 and 160 then MaxLoad = BaseMaxLoad = 58 Kg
        /// If this champion has a current stamina level of 79 then MaxLoad = 58 / 2 + ((58 * 79) / (160 / 2)) = 86 Kg
        /// If this champion has a current stamina level of 40 then MaxLoad = 58 / 2 + ((58 * 40) / (160 / 2)) = 58 Kg
        /// If this champion has a current stamina level of 0 then MaxLoad = 58 / 2 + ((58 * 0) / (160 / 2)) = 29 Kg
        /// As a conclusion, keeping your stamina level between a half and a quarter of its maximum value allows you to carry more weight!
        /// </remarks>
        /// <value>BaseMaxLoad = (8 x CurrentStrength + 100) / 10 Kg</value>
        [XmlIgnore]
        public int Load 
        { 
            get
            {
                // BaseMaxLoad = (8 x CurrentStrength + 100) / 10 Kg
                int BaseMaxLoad = (8*Attributes.Strength.Current + 100)/10;

                // If Stamina >= MaxStamina/2 Then MaxLoad is equal to BaseMaxLoad
                if (Attributes.Stamina.Current >= Attributes.Stamina.Max / 2) return BaseMaxLoad;

                //If Stamina < MaxStamina/2 Then MaxLoad is equal to BaseMaxLoad / 2 + ((BaseMaxLoad * Stamina) / (MaxStamina / 2))
                if (Attributes.Stamina.Current < Attributes.Stamina.Max / 2)
                {
                    //MaxLoad is equal to BaseMaxLoad / 2 + ((BaseMaxLoad * Stamina) / (MaxStamina / 2))
                    return BaseMaxLoad / 2 + ((BaseMaxLoad * Attributes.Stamina.Current) / (Attributes.Stamina.Max / 2));
                }

                return 999;
            }
        }		
		
        /// <summary>
        /// If player attacks, he/she have action panels disable for some time.
        /// </summary>
        public int DisabledDuration { get; set; }

        /// <summary>
        /// Prepeared spell in spellsheet
        /// </summary>
        public string SpellSheetSpell { get; set; }

        /// <summary>
        /// Flag if actions for right hand are diplayed
        /// </summary>
        public bool ActionOptionsAreDisplayed_Right { get; set; }

        /// <summary>
        /// Flag if actions for left hand are diplayed
        /// </summary>
        public bool ActionOptionsAreDisplayed_Left { get; set; }

        /// <summary>
        /// Where in dungeon is this creature located.
        /// </summary>
        public DungeonLoc Location { get; set; }


        /// <summary>
        /// The amount of time before you can make another action (1/6ths of a second).
        /// </summary>
        public float Fatique { get; set; }

        /// <summary>
        /// Defense modifier applied until the champion can make an action again. Shield, etc...
        /// </summary>
        public int DefenseModifier { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public Directions Facing { get; set; }

        public int MaxRecentDamage { get; set; }
		
        /// <summary>
        /// If monster, how many times u can cast spell.
        /// </summary>
		[XmlAttribute]
		public int MovementSpeed { get; set; }		

        [XmlIgnore]
        public int OuchesCount
        {
            get
            {
                int wounds = 0;

                if (Ouches.HurtFeet) wounds++;
                if (Ouches.HurtHead) wounds++;
                if (Ouches.HurtLeftHand) wounds++;
                if (Ouches.HurtLegs) wounds++;
                if (Ouches.HurtRightHand) wounds++;
                if (Ouches.HurtTorso) wounds++;
                if (Ouches.HurtWeapon) wounds++;

                return wounds;
            }
        }

        public CHARFLAGS CharFlags { get; set; }

        public STATE_OF_FEAR Fear { get; set; }

        public int SpellCharges { get; set; }

        #endregion

        public CreatureGfx Gfx
        {
            get
            {
                if (!string.IsNullOrEmpty(GfxId))
                {
                    return Root.I.CreatureSystem.GetGfx(GfxId);
                }

                return null;
            }
        }

        private CreatureLogic _l;
        public CreatureLogic L
        {
            get
            {
                if (_l == null)
                    _l = new CreatureLogic(this);

                return _l;
            }
        }
    }
}
